#include "stdafx.h"
#include "CreateOccObject.h"
#include <BRepPrimAPI_MakeBox.hxx>

#include <TopExp_Explorer.hxx>
#include <gce_MakeDir.hxx>

#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Compound.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <GC_MakeSegment.hxx>
#include <GC_MakeArcOfCircle.hxx>

#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <Geom_TrimmedCurve.hxx>


CreateOccObject::CreateOccObject(QObject *parent) : OccObjectBase(parent)
{
}


CreateOccObject::~CreateOccObject()
{
}


QVariant CreateOccObject::CreateBox(ZMReal x, ZMReal y, ZMReal z)
{
	BRepPrimAPI_MakeBox c(x,y,z);
	return ShapeToVariant(c.Shape());
}
QVariant CreateOccObject::CreateSphere(ZMReal r)
{
	BRepPrimAPI_MakeSphere s(r);
	return ShapeToVariant(s.Shape());
}

QVariant CreateOccObject::CreatePoint(ZMReal x, ZMReal y, ZMReal z)
{
	return ToVariant(gp_Pnt(x, y, z));
}

QVariant CreateOccObject::CreateVector(ZMReal x, ZMReal y, ZMReal z)
{
	return ToVariant(gp_Vec(x, y, z));
}

QVariant CreateOccObject::CreateArcOfCircle(const gp_Pnt& pnt0, const gp_Pnt& pnt1, const gp_Pnt& pnt2, const ZMReal& fPercentBegin , const ZMReal& fPercentEnd)
{
	Handle(Geom_TrimmedCurve) anArcOfCircle = GC_MakeArcOfCircle(pnt0, pnt1, pnt2);
	ZMReal fBegin = anArcOfCircle->FirstParameter();
	ZMReal fEnd = anArcOfCircle->LastParameter();


	ZMReal fDelta = fEnd - fBegin;

	//gp_Pnt gp0, gp1, gp2;
	//anArcOfCircle->D0(fBegin, gp0);
	//anArcOfCircle->D0(fEnd, gp1);
	//anArcOfCircle->D0(fBegin + fPercentEnd* fDelta, gp2);

	anArcOfCircle->SetTrim(fBegin + fPercentBegin* fDelta, fBegin + fPercentEnd* fDelta);
	return ShapeToVariant(BRepBuilderAPI_MakeEdge(anArcOfCircle).Shape());
}

QVariant CreateOccObject::CreateSegment(const gp_Pnt& pntFrom, const gp_Pnt& pntTo)
{
	Handle(Geom_TrimmedCurve) aSegment1 = GC_MakeSegment(pntFrom, pntTo);
	TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge(aSegment1).Edge();
	return ShapeToVariant(anEdge1);
}

QVariant CreateOccObject::Test(const QVariant& data)
{
	
	QList<QVariant> vData = data.toList();
	return QVariant();
}

QVariant CreateOccObject::CreateFaceFromEdge(const QVariant& varEdge)
{
	ZMVector<TopoDS_Edge> lsEdge = ChangeToEdge(FromVariant<TopoDS_Shape>(varEdge));

	BRepBuilderAPI_MakeWire mkWire;
	for (const TopoDS_Edge& edge : lsEdge)
	{
		mkWire.Add(edge);
	}

	TopoDS_Face face = BRepBuilderAPI_MakeFace(mkWire.Wire());
	return ShapeToVariant(face);
}

QVariant CreateOccObject::CreateFaceFromWire(const QVariant&  varWire)//param: QVector<TopoDS_Wire>
{
	ZMVector<TopoDS_Wire> lsWire = ChangeToWire(FromVariant<TopoDS_Shape>(varWire));
	BRepBuilderAPI_MakeWire mkWire;
	for (const TopoDS_Wire& wire : lsWire)
	{
		mkWire.Add(wire);

	}

	TopoDS_Face face = BRepBuilderAPI_MakeFace(mkWire.Wire());
	return ShapeToVariant(face);
}

QVariant CreateOccObject::CreateWireFromEdge(const QVariant& varEdge)
{
	ZMVector<TopoDS_Edge> lsEdge = ChangeToEdge(FromVariant<TopoDS_Shape>(varEdge));
	BRepBuilderAPI_MakeWire mkWire;
	for (const TopoDS_Edge& edge : lsEdge)
	{
		mkWire.Add(edge);
	}
	return ShapeToVariant(mkWire.Wire());
}

QVariant CreateOccObject::CreateWireFromWire(const QVariant& varWire)//param: QVector<TopoDS_Wire>
{
	ZMVector<TopoDS_Wire> lsWire = ChangeToWire(FromVariant<TopoDS_Shape>(varWire));
	BRepBuilderAPI_MakeWire mkWire;
	for (const TopoDS_Wire& wire : lsWire)
	{
		mkWire.Add(wire);
	}
	return ShapeToVariant(mkWire.Shape());
}

QVariant CreateOccObject::CreateTransForm_Tranlate(ZMReal x, ZMReal y, ZMReal z)
{
	gp_Trsf ret;
	ret.SetTranslation(gp_Vec(x, y, z));
	return ToVariant(ret);
}

QVariant CreateOccObject::CreateTransForm_Rotate(const gp_Pnt& axisFrom, const gp_Vec& axis, ZMReal angle)
{
	gp_Trsf ret;
	gp_Ax1 xAxis;
	xAxis.SetLocation(axisFrom);
	xAxis.SetDirection(gce_MakeDir(axis));
	ret.SetRotation(xAxis,angle);
	return ToVariant(ret);
}

QVariant CreateOccObject::CreateTransForm_Scale(ZMReal s)
{
	gp_Trsf ret;
	ret.SetScale(gp_Pnt(0, 0, 0), s);
	return ToVariant(ret);
}

QVariant CreateOccObject::CreateTransForm_Mirror(const gp_Pnt& axisFrom, const gp_Vec& vec)
{
	gp_Trsf ret;
	gp_Ax1 xAxis;
	xAxis.SetLocation(axisFrom);
	xAxis.SetDirection(gce_MakeDir(vec));
	ret.SetMirror(xAxis);
	return ToVariant(ret);
}

QVariant CreateOccObject::CreateTransForm_Mirror(const gp_Pnt& pnt)
{
	gp_Trsf ret;
	ret.SetMirror(pnt);
	return ToVariant(ret);
}